package com.imooc.sell.service.impl;

import com.imooc.sell.Enums.OrderStatusEunm;
import com.imooc.sell.Enums.PayStatusEnum;
import com.imooc.sell.Enums.ResultEnum;
import com.imooc.sell.converter.OrderMsater2OrderDtoConverter;
import com.imooc.sell.dataobject.OrderDetail;
import com.imooc.sell.dataobject.OrderMaster;
import com.imooc.sell.dataobject.ProductInfo;
import com.imooc.sell.dto.CarTo;
import com.imooc.sell.dto.OrderDto;
import com.imooc.sell.exception.SellException;
import com.imooc.sell.repository.OrderDetailRepository;
import com.imooc.sell.repository.OrderMasterRepository;
import com.imooc.sell.service.OrderService;
import com.imooc.sell.service.ProductInfoService;
import com.imooc.sell.util.KeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author 小柯
 * @Date 2019/6/30  1:12
 **/
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private OrderDetailRepository orderDetailRepository;
    @Autowired
    private OrderMasterRepository orderMasterRepository;



    @Override
    @Transactional
    public OrderDto create(OrderDto orderDto) {
        String orderId = KeyUtil.genUiquekey();

        BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);

        //查询商品（数量 价格）
        for(OrderDetail orderDetail : orderDto.getOrderDetailList()){
            ProductInfo productInfo = productInfoService.findOne(orderDetail.getProductId());
            if(productInfo == null){
                throw new SellException(ResultEnum.PRODUCT_NOE_EXIST);
            }
            //计算总价 (数量乘以单价)
            orderAmount = productInfo.getProductPrice()
                    .multiply(new BigDecimal(orderDetail.getProductQuantity())).add(orderAmount);
            //订单性情入库
            BeanUtils.copyProperties(productInfo, orderDetail);
            orderDetail.setDetailId(KeyUtil.genUiquekey());
            orderDetail.setOrderId(orderId);

            orderDetailRepository.save(orderDetail);

        }



        //写入订单数据库
        OrderMaster orderMaster = new OrderMaster();
        orderDto.setOrderId(orderId);
        BeanUtils.copyProperties(orderDto, orderMaster);
        //orderMaster.setOrderId(orderId);
        orderMaster.setOrderAmount(orderAmount);
        orderMaster.setOrderStatus(OrderStatusEunm.NEW.getCode());
        orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());


        orderMasterRepository.save(orderMaster);

        //扣库存
        List<CarTo> carToList =
        orderDto.getOrderDetailList().stream().map(e ->
                new CarTo(e.getProductId(), e.getProductQuantity()))
                .collect(Collectors.toList());
        productInfoService.decreaseStock(carToList);
        return orderDto;
    }

    @Override
    public OrderDto findOne(String orderId) {
        OrderMaster orderMaster = orderMasterRepository.findOne(orderId);
        if(orderMaster == null ){
            throw  new SellException(ResultEnum.PRODUCT_NOE_EXIST);
        }
        List<OrderDetail> orderDetailList = orderDetailRepository.findByOrderId(orderId);
        if(CollectionUtils.isEmpty(orderDetailList)){
            throw new SellException(ResultEnum.PRODUCTDETIL_NOT_EXIT);
        }
        OrderDto orderDto = new OrderDto();
        BeanUtils.copyProperties(orderMaster, orderDto);
        orderDto.setOrderDetailList(orderDetailList);
        return orderDto;
    }

    @Override
    public Page<OrderDto> findList(String buyerOpenid, Pageable pageable) {

        Page<OrderMaster> orderMasterPage = orderMasterRepository.findByBuyerOpenid(buyerOpenid, pageable);

        List<OrderDto> orderDtoList = OrderMsater2OrderDtoConverter.convert(orderMasterPage.getContent());

        Page<OrderDto> orderDtoPage = new PageImpl<OrderDto>(orderDtoList, pageable, orderMasterPage.getTotalPages());

        return orderDtoPage;
    }


    /** 取消订单 */
    @Override
    @Transactional
    public OrderDto cancel(OrderDto orderDto) {
        OrderMaster orderMaster = new OrderMaster();


        //判断订单状态
        if(!orderDto.getOrderStatus().equals(OrderStatusEunm.NEW.getCode())){

            log.error("取消订单，订单状态不正确,orderId={}, OrderStatus={}", orderDto.getOrderId(),orderDto.getOrderStatus());
            throw new SellException(ResultEnum.PRODUCT_ORDER_ERROR);
        }

        orderMaster.setOrderStatus(OrderStatusEunm.CHNCEL.getCode());
        //修改订单状态
        OrderMaster updateResult = orderMasterRepository.save(orderMaster);

        BeanUtils.copyProperties(orderDto, orderMaster);

        if(updateResult == null){
            log.error("取消订单，更新状态异常 orderMaster={}" + orderMaster);
            throw  new SellException(ResultEnum.ORDER_UPDATE_FAIL);
        }
        //返回仓库
        if(CollectionUtils.isEmpty(orderDto.getOrderDetailList())){
            log.error("【取消订单】 订单中无商品详情, orderDto={}" + orderDto);
            throw new SellException(ResultEnum.REDER_ORDERDETEIL_ISEMPTY);
        }
        List<CarTo> carToList = orderDto.getOrderDetailList().stream().map(e ->
                new CarTo(e.getProductId(), e.getProductQuantity())).collect(Collectors.toList());
        productInfoService.increaseStock(carToList);

        //如果已经支付，需要返回退款
        if(orderDto.getPayStatus().equals(PayStatusEnum.SUCCESS.getCode())){
            //TODO
        }


        return orderDto;
    }

    @Override
    @Transactional
    public OrderDto finish(OrderDto orderDto) {
        //判断订单状态

        if(!orderDto.getOrderStatus().equals(OrderStatusEunm.NEW.getCode())){
            log.error("【完结订单】 订单状态不正确, orderId={}, orderStatus={}" +  orderDto.getOrderId(),orderDto.getOrderStatus());
            throw new SellException(ResultEnum.PRODUCT_ORDER_ERROR);
        }
        //修改订单状态
        orderDto.setOrderStatus(OrderStatusEunm.FINISHED.getCode());
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderDto, orderMaster);
        OrderMaster orderMasterUpdate = orderMasterRepository.save(orderMaster);
        if(orderMasterUpdate == null){
            log.error("完结订单，更新状态异常 orderMaster={}" + orderMaster);
            throw  new SellException(ResultEnum.ORDER_UPDATE_FAIL);
        }


        return orderDto;
    }

    @Override
    @Transactional
    public OrderDto paid(OrderDto orderDto) {
        //判断订单状态
        if(!orderDto.getOrderStatus().equals(OrderStatusEunm.NEW.getCode())){
            log.error("【订单支付异常】 订单状态不正确, orderId={}, orderStatus={}" +  orderDto.getOrderId(),orderDto.getOrderStatus());
            throw new SellException(ResultEnum.PRODUCT_ORDER_ERROR);
        }
        //判断支付状态
        if(orderDto.getPayStatus().equals(PayStatusEnum.WAIT.getCode())){
            log.error("【订单支付异常】 支付状态 orderDto.getPayStatus={}" + orderDto.getPayStatus());
            throw  new SellException(ResultEnum.OREDER_PAY_ISEMPTY);
        }
        //修改支付状态
        orderDto.setPayStatus(PayStatusEnum.SUCCESS.getCode());
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderDto, orderMaster);
        OrderMaster orderMasterUpdate = orderMasterRepository.save(orderMaster);
        if(orderMasterUpdate == null){
            log.error("【订单支付完成】，更新状态失败 orderMaster={}" + orderMaster);
            throw  new SellException(ResultEnum.ORDER_UPDATE_FAIL);
        }


        return orderDto;
    }
}
